-module(randomtest).
-compile(export_all).

%% to run:
%% Procs = start_program().
%% printAll(Procs, 5). %% Let each print 5 values.
%% seedAll(Procs). %% Seed all.
%% printAll(Procs, 5).
%% seedAll(Procs). %% Seed again
%% printAll(Procs, 5).

%% Start program
start_program() ->
   {S1, S2, S3} = now(),
   io:fwrite("Initial seed: ~B ~B ~B\n", [S1, S2, S3]),
   random:seed({S1, S2, S3}),
   All = spawn_procs(1000),
   All.

%% Creating process pool
spawn_procs(Len) ->
   [spawn(randomtest,
          proc,
          []
         )
   || _<-lists:seq(1,Len)].
   
%% Tell all processes to print a random value
printAll([]) -> ok;
printAll([X|Xs]) ->
   X ! print,
   printAll(Xs).

%% Seed all processes' PRNGs with random values.
seedAll([]) -> ok;
seedAll([P|Ps]) ->
   S1 = random:uniform(1000),
   S2 = random:uniform(1000),
   S3 = random:uniform(1000),
   P ! {seed, {S1, S2, S3}},
   seedAll(Ps).

proc() ->
   receive
      print ->
         Val = random:uniform(1000),
         io:fwrite("Proc ~p Val ~B\n", [self(), Val]),
         proc();
      {seed, {V1, V2, V3}} ->
         io:fwrite("Proc ~p Seed ~B ~B ~B\n", [self(), V1, V2, V3]),
         random:seed({V1, V2, V3}),
         proc();
      die -> ok
   end.


